package cn.sciento.core.observer;

import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import cn.sciento.core.oauth.CustomUserDetails;
import cn.sciento.core.oauth.DetailsHelper;
import cn.sciento.core.util.AsyncTask;
import cn.sciento.core.util.CommonExecutor;
import org.apache.commons.collections4.CollectionUtils;


public class AsyncEventBus<T> extends EventBus<T> {
  private final ThreadPoolExecutor executor;
  
  public AsyncEventBus(String identifier, List<? extends Observer<T>> observers, ThreadPoolExecutor executor) {
    super(identifier, observers);
    this.executor = executor;
  }
  
  @Override
  public void notifyObservers(T target) {
    notifyObservers(target);
  }
  
  @Override
  public void notifyObservers(final T target, Object... args) {
    if (CollectionUtils.isEmpty(this.observers))
      return; 
    final CustomUserDetails self = DetailsHelper.getUserDetails();
    List<AsyncTask<Boolean>> tasks = this.observers.stream().map(o -> new AsyncTask<Boolean>() {
          public String taskName() {
            return o.getClass().getSimpleName();
          }
          
          public Boolean doExecute() {
            if (self != null)
              DetailsHelper.setCustomUserDetails(self); 
            o.update(target, args);
            return Boolean.TRUE;
          }
        }).collect(Collectors.toList());
    CommonExecutor.batchExecuteAsync(tasks, this.executor, this.identifier);
  }
}
